<script lang="ts">
	import { type TableState } from '../store/table-state.svelte';
	import VirtualScroll from '$lib/components/Basic/VirtualScroll/VirtualScroll.svelte';
	import Scrollbar from '$lib/components/Basic/Scrollbar/Scrollbar.svelte';
	import CheckSquare from '$lib/components/Form/Checkbox/CheckSquare.svelte';
	import LoadingBar from '$lib/components/ExceptionPage/LoadingBar.svelte';

	interface Props {
		tableState: TableState;
		virtualized: boolean;
		actRowHeight: number;
		size: 'sm' | 'md' | 'lg';
		stripe?: boolean;
		multiple: boolean;
		tbodyClass?: string;
		border?: boolean;
		rowClass?: (row: any, index: number) => string;
		// 回调
		onScroll?: (e: { scrollTop: number; scrollLeft: number }) => void;
	}

	let {
		tableState,
		virtualized,
		actRowHeight,
		size,
		stripe,
		multiple,
		tbodyClass,
		border = false,
		rowClass = () => '',
		onScroll
	}: Props = $props();
	let scrollContainerRef: HTMLElement | null = $state(null);

	let refreshScrollbar: () => void | Promise<void> = $state(() => {});
</script>

<!-- 根据 virtualized 切换 -->
{#if virtualized}
	{#if tableState.isLoading}
		<div class="loading" style:top={`${tableState.headerData.maxDepth * actRowHeight - 2}px`}>
			<LoadingBar />
		</div>
	{/if}
	<VirtualScroll
		data={tableState.processedData}
		itemHeight={actRowHeight}
		onScrollPositionChange={onScroll}
		bufferSize={10}
		styles="flex:1"
		scrollTypeX="auto"
		scrollTypeY="auto"
		bind:scrollContainerRef
		onScrollbarChange={(
			hasVerticalScroll: boolean,
			scrollbarWidth: number,
			hasHorizontalScroll: boolean,
			scrollbarHeight: number
		) => {
			tableState.bodyScrollbarWidth = hasVerticalScroll ? 10 : 0;
			tableState.bodyScrollbarHeight = hasHorizontalScroll ? 10 : 0;
		}}
	>
		{#snippet children({ visibleData })}
			<!-- 表体：虚拟滚动，使用简化的grid布局层级 -->
			<div
				class={`table-tbody virtual-table-tbody ${tbodyClass}}`}
				class:is-horizontal={tableState.bodyScrollbarWidth > 0}
				class:table--border={border}
			>
				<!-- 性能优化：使用优化的key生成函数，并预先计算索引 -->
				<!-- 正确使用Svelte each循环的key语法 -->
				{#each visibleData as row, index (row.id)}
					<!-- 计算原始索引（关键！） -->
					<div class={`table-tr ${stripe && index % 2 === 1 ? 'table-tr--stripe' : ''}`}>
						{#if multiple}
							<div class="check-box-container">
								<CheckSquare
									{size}
									checked={tableState.selectionVersion > 0 &&
										(tableState.isExcludeMode
											? !tableState.selectedKeys.has(row.id)
											: tableState.selectedKeys.has(row.id))}
									onChange={(checked) => tableState.toggleRowSelection(row.id, checked)}
								/>
							</div>
						{/if}
						<!-- 性能优化：减少嵌套循环中的属性访问 -->
						{#each tableState.columns as col}
							<div class="table-td" style:--text-align={col.align}>
								{#if col.slots.cell}
									{@render col.slots.cell({ row, index: index, column: col })}
								{:else}
									{row[col.key]}
								{/if}
							</div>
						{/each}
					</div>
				{/each}
			</div>
		{/snippet}
	</VirtualScroll>
{:else}
	<Scrollbar
		onScrollPositionChange={onScroll}
		scrollWidth={10}
		style={`min-height: 0;padding: 0;flex:1;`}
		scrollTypeX="auto"
		scrollTypeY="auto"
		bind:checkScrollbar={refreshScrollbar}
		bind:scrollContainerRef
		onScrollbarChange={(
			hasVerticalScroll: boolean,
			scrollbarWidth: number,
			hasHorizontalScroll: boolean,
			scrollbarHeight: number
		) => {
			tableState.bodyScrollbarWidth = hasVerticalScroll ? 10 : 0;
			tableState.bodyScrollbarHeight = hasHorizontalScroll ? 10 : 0;
		}}
	>
		<!-- 表体：自然滚动，使用简化的grid布局层级 -->
		<div
			class={`table-tbody ${tbodyClass}`}
			style:will-change="transform"
			class:is-horizontal={tableState.bodyScrollbarWidth > 0}
			class:table--border={border}
		>
			{#each tableState.processedData as row, rowIndex (row.id || rowIndex)}
				<div
					class={`table-tr ${rowClass(row, rowIndex)} ${stripe && rowIndex % 2 === 1 ? 'table-tr--stripe' : ''}`}
				>
					{#if multiple}
						<div class="check-box-container">
							<CheckSquare
								{size}
								checked={tableState.selectionVersion > 0 &&
									(tableState.isExcludeMode
										? !tableState.selectedKeys.has(row.id)
										: tableState.selectedKeys.has(row.id))}
								onChange={(checked) => tableState.toggleRowSelection(row.id, checked)}
							/>
						</div>
					{/if}
					{#each tableState.columns as col (col.key)}
						<div class="table-td" style:--text-align={col.align}>
							{#if col.slots.cell}
								{@render col.slots.cell({ row, index: rowIndex, column: col })}
							{:else}
								{row[col.key]}
							{/if}
						</div>
					{/each}
				</div>
			{/each}
		</div>
	</Scrollbar>
{/if}

<style lang="scss">
	@use '../styles/tableBody.scss';
</style>
